package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.dto.SysDepartmentDTO;
import com.nineclock.system.entity.ExcelMember;
import com.nineclock.system.entity.ExcelMemberListener;
import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SysCompanyUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;

import java.util.List;

import java.util.stream.Collectors;

@Service
@Slf4j
public class SysCompanyUserServiceImpl implements SysCompanyUserService {

    @Autowired
    SysCompanyUserMapper companyUserMapper;

    @Autowired
    RedisTemplate redisTemplate;
    @Override
    public SysCompanyUserDTO getCurrentAdmin() {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        SysCompanyUser companyUser = companyUserMapper.queryMainAdminCompanyUser(companyId);

        if (companyUser==null){
            throw new NcException(ResponseEnum.COMPANY_ADMIN_NOT_EXISTS);
        }

        return BeanHelper.copyProperties(companyUser,SysCompanyUserDTO.class);
    }

    @Override
    public List<SysCompanyUserDTO> queryCompanyMemberList() {
        Long companyId = CurrentUserHolder.get().getCompanyId();

        LambdaQueryWrapper<SysCompanyUser> wrapper =new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId,companyId);
        wrapper.eq(SysCompanyUser::getEnable,1);

        List<SysCompanyUser> companyUsers = companyUserMapper.selectList(wrapper);

        if (CollectionUtil.isEmpty(companyUsers)) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        List<SysCompanyUserDTO> companyUserDTOS = BeanHelper.copyWithCollection(companyUsers, SysCompanyUserDTO.class);

        return companyUserDTOS;
    }

    /**
     * 分页查询部门下的员工列表
     * @param page
     * @param pageSize
     * @param keyword
     * @param departmentId
     * @return
     */
    @Override
    public PageResult<SysCompanyUserDTO> members(Integer page, Integer pageSize, String keyword, Long departmentId) {
//查询当前部门下的所有的子部门的id集合(包含当前部门id ，子部门id)

        List<Long> departmentIds = new ArrayList<>();
        //如果前端部门id为0 ，查询所有的部门id
        if(departmentId != 0 ){
            departmentIds.add(departmentId);
        }
        this.queryChildrenDepartmentIds(departmentIds, departmentId);



        //定义员工的queryWrapper对象
        LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();
        companyUserQw.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
        companyUserQw.in(SysCompanyUser::getDepartmentId, departmentIds);
        //分页模型对象（要求包含 当前页 ，每页条数）
        Page<SysCompanyUser> companyUserPage = new Page(page , pageSize);

        //keyword
        if(StrUtil.isNotEmpty(keyword)){
            companyUserQw.and(queryWrapper -> {
                queryWrapper.like(SysCompanyUser::getUserName, keyword)
                        .or().like(SysCompanyUser::getWorkNumber, keyword)
                        .or().like(SysCompanyUser::getMobile, keyword);
            });
        }
        //分页查询
        companyUserPage = companyUserMapper.selectPage(companyUserPage, companyUserQw);
        List<SysCompanyUser> records = companyUserPage.getRecords();
        List<SysCompanyUserDTO> companyUserDTOList = BeanHelper.copyWithCollection(records, SysCompanyUserDTO.class);
        for (SysCompanyUserDTO companyUserDTO : companyUserDTOList) {
            //创建部门对象
            SysDepartmentDTO departmentDTO = new SysDepartmentDTO();
            departmentDTO.setId(companyUserDTO.getDepartmentId());
            departmentDTO.setName(companyUserDTO.getDepartmentName());
            //放到员工属性中
            companyUserDTO.setDepartment(departmentDTO);
        }

        //封装PageResult对象
        return new PageResult(companyUserPage.getTotal(),
                companyUserPage.getPages(), companyUserDTOList);
    }

    /**
     * 批量导入员工数据
     * @param excelFile
     */
    @Override
    public void importData(MultipartFile excelFile) throws IOException {

        if (excelFile == null) {
            throw new NcException(ResponseEnum.UPLOAD_FILE_NOT_FOUND);
        }

        EasyExcel.read(excelFile.getInputStream(),
                        ExcelMember.class,
                        new ExcelMemberListener(this))
                .sheet(0)
                .doRead();
    }
    @Autowired
    SysUserMapper userMapper;

    @Autowired
    SysCompanyUserRoleMapper companyUserRoleMapper;

    @Autowired
    SysRoleMapper sysRoleMapper;
    /**
     * 处理解析完毕之后的员工数据, 进行数据组装及持久化操作
     * @param memberList
     */
    @Override
    public void handleParsedData(List<ExcelMember> memberList) {

        for (ExcelMember excelMember : memberList) {
            // 保存SysUser用户数据
            SysUser sysUser = new SysUser();
            //判断手机号邮箱号是否已注册
            LambdaQueryWrapper<SysUser> user=new LambdaQueryWrapper<>();
            user.eq(SysUser::getMobile,excelMember.getMobile())
                    .or().eq(SysUser::getEmail,excelMember.getEmail());

            Integer count = userMapper.selectCount(user);
            if (count != 0) {
                throw new NcException(ResponseEnum.USER_MOBILE_EMAIL_EXISTS);
            }

            //判断工号是否已存在
            LambdaQueryWrapper<SysCompanyUser> companyUser=new LambdaQueryWrapper<>();

            companyUser.eq(SysCompanyUser::getDepartmentId,excelMember.getWorkNumber());
            Integer count1 = companyUserMapper.selectCount(companyUser);
            if (count1 != 0) {
                throw new NcException(ResponseEnum.WROK_NUM_EXISTS);
            }
            //1.3 封装系统用户数据 , 对密码进行加密
            sysUser.setMobile(excelMember.getMobile());
            sysUser.setEmail(excelMember.getEmail());
            sysUser.setUsername(excelMember.getName());

            sysUser.setCreateTime(excelMember.getEntryTime());
            sysUser.setStatus(excelMember.getEnable().equals("可用")?(short)1:(short)0);
            sysUser.setPassword(new BCryptPasswordEncoder().encode("123456"));

            userMapper.insert(sysUser);

            SysCompanyUser sysCompanyUser=new SysCompanyUser();

            //组装员工的部门信息
            sysCompanyUser.setUserId(sysUser.getId());
            sysCompanyUser.setUserName(excelMember.getName());
            sysCompanyUser.setMobile(excelMember.getMobile());
            sysCompanyUser.setEmail(excelMember.getEmail());
            sysCompanyUser.setRemark(excelMember.getDesc());
            sysCompanyUser.setEnable(excelMember.getEnable().equals("可用")?(short)1:(short)0);
            sysCompanyUser.setPost(excelMember.getPosition());
            sysCompanyUser.setCompanyId(CurrentUserHolder.get().getCompanyId());
            sysCompanyUser.setCompanyName(CurrentUserHolder.get().getCompanyName());
            sysCompanyUser.setOfficeAddress(excelMember.getWorkAddr());
            sysCompanyUser.setTimeEntry(excelMember.getEntryTime());
            sysCompanyUser.setWorkNumber(excelMember.getWorkNumber());

            //组装员工的部门信息
            String departmentName = excelMember.getDepartmentName();
            if(StrUtil.isNotEmpty(departmentName)){
                LambdaQueryWrapper<SysDepartment> depQueryWrapper = new LambdaQueryWrapper<>();
                depQueryWrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
                depQueryWrapper.eq(SysDepartment::getName, departmentName);

                SysDepartment sysDepartment = departmentMapper.selectOne(depQueryWrapper);
                if(sysDepartment != null){
                    sysCompanyUser.setDepartmentId(sysDepartment.getId());
                    sysCompanyUser.setDepartmentName(departmentName);
                }
            }
            //保存企业员工
            companyUserMapper.insert(sysCompanyUser);

            //2.4 保存员工的角色信息
            String roleName = excelMember.getRoleName();
            if(StrUtil.isNotEmpty(roleName)){
                LambdaQueryWrapper<SysRole> roleQueryWrapper = new LambdaQueryWrapper<>();
                roleQueryWrapper.eq(SysRole::getRoleDesc, roleName);
                roleQueryWrapper.eq(SysRole::getCompanyId, CurrentUserHolder.get().getCompanyId());

                SysRole sysRole = sysRoleMapper.selectOne(roleQueryWrapper);
                if(sysRole != null){
                    SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
                    companyUserRole.setCompanyId(CurrentUserHolder.get().getCompanyId());
                    companyUserRole.setCompanyUserId(sysCompanyUser.getId());
                    companyUserRole.setRoleId(sysRole.getId());

                    companyUserRoleMapper.insert(companyUserRole);
                }
            }

        }

    }

    /**
     * 根据部门ID, 查询该部门下的员工数量
     * @param departmentIds
     * @return
     */
    @Override
    public Integer queryUserCountByDepartmentIds(List<Long> departmentIds) {
        List ids=new ArrayList<>();

        ids.addAll(departmentIds);

        for (Long departmentId : departmentIds) {
            this.queryChildrenDepartmentIds( ids,departmentId);
        }

        LambdaQueryWrapper<SysCompanyUser> companyUserQw=new LambdaQueryWrapper<>();
        companyUserQw.in(SysCompanyUser::getDepartmentId,ids);
        companyUserQw.eq(SysCompanyUser::getEnable,(short)1);


        Integer count = companyUserMapper.selectCount(companyUserQw);
        return count;
    }

    //根据企业ID查询企业的主管理员信息
    @Override
    public SysCompanyUserDTO queryAdminByCompanyId(Long companyId) {
        SysCompanyUser companyUser = companyUserMapper.queryMainAdminCompanyUser(companyId);
        return BeanHelper.copyProperties(companyUser, SysCompanyUserDTO.class);
    }

    @Override
    public List<SysCompanyUserDTO> queryAllUserByCompanyId(Long companyId) {
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        wrapper.eq(SysCompanyUser::getEnable, 1);
        List<SysCompanyUser> companyUserList = companyUserMapper.selectList(wrapper);
        if(CollectionUtil.isNotEmpty(companyUserList)){
            return BeanHelper.copyWithCollection(companyUserList, SysCompanyUserDTO.class);
        }
        return null;
    }

    @Autowired
    SysDepartmentMapper departmentMapper;

    private void  queryChildrenDepartmentIds(List<Long> departmentIds , Long parentId) {
        LambdaQueryWrapper<SysDepartment> departmentQw = new LambdaQueryWrapper<>();
        departmentQw.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        departmentQw.eq(SysDepartment::getParentId, parentId);
        List<SysDepartment> departmentList = departmentMapper.selectList(departmentQw);
        if(CollectionUtil.isNotEmpty(departmentList)) {
            List<Long> ids = departmentList.stream().map(sysDepartment -> {
                return sysDepartment.getId();
            }).collect(Collectors.toList());
            departmentIds.addAll(ids);
            //循环，递归查询子部门的id
            for (Long id : ids) {
                this.queryChildrenDepartmentIds(departmentIds,id);
            }
        }
    }
}
